package net.heimeng.bphelper;

import android.content.Context;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.widget.LinearLayout;

import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

/**
 * 悬浮窗视图
 */
public class FloatingBallView extends LinearLayout implements View.OnClickListener {
    private final WindowManager windowManager;
    private WindowManager.LayoutParams layoutParams;
    private long lastDownTime;
    private float lastDownX;
    private float lastDownY;
    private boolean isLongTouch;
    private boolean isTouching;
    private float touchSlop;
    private final static long LONG_CLICK_LIMIT = 200;
    private final static int TIME_COUNT = 0;
    private int statusBarHeight;
    private int currentMode;
    private final int time = 0;
    private final static int MODE_NONE = 0x000;
    private final static int MODE_MOVE = 0x001;
    private int offsetToParent;
    private int offsetToParentY;
    private Context context;

    public FloatingBallView(Context context) {
        super(context);
        this.context = context;
        windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        initView();
    }

    private void initView() {
        View view = inflate(getContext(), R.layout.floating_ball, this);
        touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
        currentMode = MODE_NONE;
        statusBarHeight = getStatusBarHeight(view);
        offsetToParent = dip2px(25);
        offsetToParentY = statusBarHeight + offsetToParent;
        view.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, final MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        isTouching = true;
                        lastDownTime = System.currentTimeMillis();
                        lastDownX = event.getX();
                        lastDownY = event.getY();
                        postDelayed(() -> {
                            if (isLongTouch()) {
                                isLongTouch = true;
                                Log.d("悬浮球", "长按事件被触发");
                            } else {
                                // TODO: 点击事件，此处应该编写唤起悬浮窗的功能，目前是单击自动关闭悬浮球
                                Log.d("悬浮球", "点击事件被触发");
                                performClick();
                                FloatWindow.showPopupWindow(context);
                            }
                        }, LONG_CLICK_LIMIT);
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (!isLongTouch && isTouchSlop(event)) {
                            return true;
                        }
                        if (isLongTouch && (currentMode == MODE_NONE || currentMode == MODE_MOVE)) {
                            layoutParams.x = (int) (event.getRawX() - offsetToParent);
                            layoutParams.y = (int) (event.getRawY() - offsetToParentY);
                            // 不断刷新悬浮窗的位置
                            windowManager.updateViewLayout(FloatingBallView.this, layoutParams);
                            currentMode = MODE_MOVE;
                        }
                        break;
                    case MotionEvent.ACTION_CANCEL:
                    case MotionEvent.ACTION_UP:
                        isTouching = false;
                        if (isLongTouch) {
                            isLongTouch = false;
                        }
                        currentMode = MODE_NONE;
                        break;
                }
                return true;
            }
        });
    }

    /**
     * 判断是否长按
     *
     * @return 是否长按
     */
    private boolean isLongTouch() {
        long time = System.currentTimeMillis();
        return isTouching && currentMode == MODE_NONE && (time - lastDownTime >= LONG_CLICK_LIMIT);
    }

    /**
     * 判断是否是轻微滑动
     *
     * @param event 事件
     * @return 是否轻微滑动
     */
    private boolean isTouchSlop(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        return Math.abs(x - lastDownX) < touchSlop && Math.abs(y - lastDownY) < touchSlop;
    }

    public void setLayoutParams(WindowManager.LayoutParams params) {
        layoutParams = params;
    }

    /**
     * 获取通知栏高度
     *
     * @param view 视图
     * @return 通知栏的高度
     */
    public int getStatusBarHeight(View view) {
        WindowInsetsCompat windowInsets = ViewCompat.getRootWindowInsets(view);
        if (windowInsets != null) {
            return windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()).top;
        }
        return 0;
    }

    public int dip2px(float dip) {
        return (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, dip, getContext().getResources().getDisplayMetrics()
        );
    }

    @Override
    public void onClick(View v) {

    }
    public void removeFromWindowManager() {
        if (windowManager != null && layoutParams != null) {
            windowManager.removeViewImmediate(this);
        }
    }
}